#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h> 
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include "mqueue.h"


/*
 * Funções auxiliares.
 */
static void send_msg_deamon(Msg *msg);
static void list_process(Msg *msg);
static void print_process(Msg *msg, int *is_first);
const char *format(const time_t *timep);


/*
 * Main.
 */
int main()
{
	Msg msg = { 0 };
	
	mqin = mqueue_obtain_in();
	mqout = mqueue_obtain_out();
	send_msg_deamon(&msg);
	list_process(&msg);
	
	return 0;
}


/*
 * Envia mensagem ao deamon (executa_proc) avisando que ele precisa informar os
 * processos para serem listados.
 */
static void send_msg_deamon(Msg *msg)
{
	msg->type = MSG_LIST;
	if (msgsnd(mqin, msg, sizeof(Job), 0) < 0) {
		perror("Erro ao enviar mensagem ao deamon");
		exit(1);
	}
}


/*
 * Fica em loop infinito recebendo mensagens e imprimindo.
 */
static void list_process(Msg *msg)
{
	int first = 1;
	
	for(;;) {
		
		/* Recebe a mensagem. */
		if(msgrcv(mqout, msg, sizeof(Job), MSG_LIST, 0) < 0) {
			perror("Erro ao receber a lista de processos agendados");
			exit(1);
		}
		
		/* Se a mensagem estiver vazia, acabaram os processos. */
		if (msg->job.id == 0) {
			return;
		}
		
		/* Senão, pode imprimir essa mensagem. */
		print_process(msg, &first);
	}
}


/*
 * Imprime um processo na tela.
 */
static void print_process(Msg *msg, int *is_first)
{
	/* Se for o primeiro processo, imprime primeiro a linha de cabeçalho. */
	if (*is_first) {
		*is_first = 0;
		printf("%-15s%-15s%-15s%-15s\n",
				"Job", "Command", "hh:mm:ss", "n");
	}

	/* Imprime um processo por linha */
	printf("%-15d%-15s%-15s%-15d\n",
			msg->job.id, msg->job.command, format(&msg->job.time), msg->job.repeats);
}


/*
 * Recebe uma estrutura time_t e gera a string correspondente no formato
 * hh:mm:ss.
 */
const char *format(const time_t *timep)
{
	static char buff[10];
	const struct tm aux = *localtime(timep);
	sprintf(buff, "%d:%d:%d", aux.tm_hour, aux.tm_min, aux.tm_sec);
	return buff;
}
